package service

import (
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/gogs/git-module"
	"github.com/pkg/errors"
)

func (g *gitRepository) getProtectedBranch(repoPath string) ([]string, error) {
	hookPath := filepath.Join(repoPath, "hooks", "pre-receive")

	gitRepo, err := git.Open(repoPath)
	if err != nil {
		return nil, err
	}
	// 读取文件内容
	content, err := os.ReadFile(hookPath)
	if err != nil {
		return nil, errors.New("File reading failure")
	}
	// 使用正则表达式匹配并替换
	re := regexp.MustCompile(`--branch='([^']*)'`)
	matches := re.FindStringSubmatch(string(content))
	if len(matches) != 2 {
		return nil, errors.New("No match found")
	}
	branches := strings.Split(matches[1], ",")
	protectedBranches := make([]string, 0)
	for i := 0; i < len(branches); i++ {
		if gitRepo.HasBranch(branches[i]) {
			protectedBranches = append(protectedBranches, branches[i])
		}
	}
	return protectedBranches, nil
}

func (g *gitRepository) updateProtectedBranch(repoPath, branchName string, protected bool) error {
	hookPath := filepath.Join(repoPath, "hooks", "pre-receive")

	// 打开文件
	file, err := os.OpenFile(hookPath, os.O_RDWR, 0644)
	if err != nil {
		return errors.New("打开文件失败")
	}
	defer file.Close()

	// 读取文件内容
	content, err := os.ReadFile(hookPath)
	if err != nil {
		return errors.New("读取文件失败")
	}

	// 使用正则表达式匹配并替换
	re := regexp.MustCompile(`--branch='([^']*)'`)
	matches := re.FindStringSubmatch(string(content))
	if len(matches) != 2 {
		return errors.New("No match found")
	}
	oldValue := matches[1] // 旧值
	var newValue string    // 新值
	if protected {
		newValue = oldValue + "," + branchName
	} else {
		newValue = strings.ReplaceAll(oldValue, branchName, "")
		newValue = strings.ReplaceAll(newValue, ",,", ",")
	}
	newValue = strings.Trim(newValue, ",")
	newContent := re.ReplaceAllString(string(content), fmt.Sprintf(`--branch='%s'`, newValue))

	// 将文件指针移至文件开始位置
	_, err = file.Seek(0, 0)
	if err != nil {
		return errors.New("重设文件指针失败")
	}

	// 清空文件内容
	err = file.Truncate(0)
	if err != nil {
		return errors.New("清空文件内容失败")
	}

	// 将修改后的内容写入文件
	_, err = file.Write([]byte(newContent))
	if err != nil {
		return errors.New("写入文件失败")
	}

	return nil
}
